package org.hdl.anima.transport.support;

import org.hdl.anima.AppConf;
import org.hdl.anima.transport.Channel;
import org.hdl.anima.transport.ChannelHandler;
import org.hdl.anima.transport.ChannelHandlerDelegate;
import org.hdl.anima.transport.Codec;
import org.hdl.anima.transport.Endpoint;
import org.hdl.anima.transport.RemoteException;

import static com.google.common.base.Preconditions.checkArgument;
/**
 * 
 * @author qiuhd
 * @since  2014-7-24
 * @version V1.0.0
 */
public abstract class AbstractEndpoint implements Endpoint,ChannelHandler{
	
	protected final ChannelHandler handler;
	private volatile boolean closed = false;
	protected Codec codec ;
	protected AppConf conf ;
	
	public AbstractEndpoint(AppConf conf,ChannelHandler handler) {
		
		this(conf, handler, null);
	}
	
	public AbstractEndpoint(AppConf conf,ChannelHandler handler,Codec codec) {
		
		checkArgument(conf != null, "conf is can not be null");
		checkArgument(handler != null,"handler can not be null");
		
		this.conf = conf;
		this.handler = handler;
		this.codec = codec;
	}
	
	@Override
	public AppConf getConf() {
		return this.conf ;
	}

	@Override
	public ChannelHandler getChannelHandler() {
		if (handler instanceof ChannelHandlerDelegate) {
			return ((ChannelHandlerDelegate)handler).getChannleHandler();
		}
		return handler;
	}

	@Override
	public void close() {
		this.closed = true;
	}

	@Override
    public void close(int timeout) {
        close();
    }

	@Override
	public boolean isClosed() {
		return closed;
	}
	
	@Override
	public void connected(Channel channel) throws RemoteException {
		if (closed)
			return;
		handler.connected(channel);
	}

	@Override
	public void disconnected(Channel channel) throws RemoteException {
		handler.disconnected(channel);
	}

	@Override
	public void sent(Channel channel, Object message) throws RemoteException {
		if (closed)
			return;
		handler.sent(channel, message);
	}

	@Override
	public void received(Channel channel, Object message) throws RemoteException {
		if (closed)
			return;
		handler.received(channel, message);
	}

	@Override
	public void caught(Channel channel, Throwable t) throws RemoteException {
		handler.caught(channel, t);
	}

	public Codec getCodec() {
		return codec;
	}
	
	public void setCodec(Codec codec) {
		checkArgument(codec != null,"codec can not be null");
		this.codec = new MultiMessageCodec(codec);
	}
}

